using Sage.CloudStorage.Qiniu.Auth;
using Sage.CloudStorage.Qiniu.Config;
using Sage.CloudStorage.Qiniu.Models;
using Sage.Http.Core;
using System.Net.Http.Headers;
using System.Text;

namespace Sage.CloudStorage.Qiniu.Storage
{
    /// <summary>
    /// 数据处理管理器 - 提供数据处理相关功能
    /// </summary>
    /// <remarks>
    /// 创建数据处理管理器实例
    /// </remarks>
    /// <param name="httpManager">HTTP请求管理器</param>
    /// <param name="key">七牛云密钥信息</param>
    /// <param name="config">七牛云配置</param>
    public class OperationManager(HttpRequestManager httpManager, QiniuKey key, QiniuConfig config)
    {
        private readonly HttpRequestManager _httpManager = httpManager ?? throw new ArgumentNullException(nameof(httpManager));
        private readonly QiniuKey _key = key ?? throw new ArgumentNullException(nameof(key));
        private readonly QiniuConfig _config = config ?? throw new ArgumentNullException(nameof(config));

        /// <summary>
        /// 数据处理
        /// </summary>
        /// <param name="bucket">空间</param>
        /// <param name="key">空间文件的key</param>
        /// <param name="fops">操作(命令参数)，与 workflowTemplateId 二选一</param>
        /// <param name="pipeline">私有队列</param>
        /// <param name="notifyUrl">通知url</param>
        /// <param name="force">force参数</param>
        /// <param name="type">为 1 时开启闲时任务</param>
        /// <param name="workflowTemplateId">模版 ID，与 fops 二选一</param>
        /// <returns>pfop操作返回结果，正确返回结果包含persistentId</returns>
        public async Task<PfopResult> PfopAsync(
            string bucket,
            string key,
            string? fops = null,
            string? pipeline = null,
            string? notifyUrl = null,
            bool force = false,
            int type = 0,
            string? workflowTemplateId = null
        )
        {
            if (string.IsNullOrEmpty(fops) && string.IsNullOrEmpty(workflowTemplateId))
            {
                throw new ArgumentException("Must provide one of fops or workflowTemplateId");
            }

            // 构建请求体
            var formData = new Dictionary<string, string>
            {
                { "bucket", bucket },
                { "key", key }
            };

            if (!string.IsNullOrEmpty(fops))
            {
                formData.Add("fops", fops);
            }

            if (!string.IsNullOrEmpty(workflowTemplateId))
            {
                formData.Add("workflowTemplateID", workflowTemplateId);
            }

            if (!string.IsNullOrEmpty(notifyUrl))
            {
                formData.Add("notifyURL", notifyUrl);
            }

            if (force)
            {
                formData.Add("force", "1");
            }

            if (!string.IsNullOrEmpty(pipeline))
            {
                formData.Add("pipeline", pipeline);
            }

            if (type > 0)
            {
                formData.Add("type", type.ToString());
            }

            // 发送请求
            string url = $"{_config.GetApiHost()}/pfop/";
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);

            // 添加表单字段
            var request = _httpManager.CreateRequest(HttpMethod.Post, url)
                .WithAuthentication(authProvider);

            // 添加表单字段
            foreach (var field in formData)
            {
                request.AddFormField(field.Key, field.Value);
            }

            var result = await request.SendAsJsonAsync(QiniuJsonSerializerContext.Default.PfopResult);
            return result ?? new PfopResult();
        }

        /// <summary>
        /// 数据处理，操作字符串拼接后与另一种形式等价
        /// </summary>
        /// <param name="bucket">空间</param>
        /// <param name="key">空间文件的key</param>
        /// <param name="fops">操作(命令参数)列表</param>
        /// <param name="pipeline">私有队列</param>
        /// <param name="notifyUrl">通知url</param>
        /// <param name="force">force参数</param>
        /// <returns>操作返回结果，正确返回结果包含persistentId</returns>
        public async Task<PfopResult> PfopAsync(string bucket, string key, string[] fops, string? pipeline = null, string? notifyUrl = null, bool force = false)
        {
            string ops = string.Join(";", fops);
            return await PfopAsync(bucket, key, ops, pipeline, notifyUrl, force);
        }

        /// <summary>
        /// 查询pfop操作处理结果(或状态)
        /// </summary>
        /// <param name="persistentId">持久化ID</param>
        /// <returns>操作结果</returns>
        public async Task<PrefopResult> PrefopAsync(string persistentId)
        {
            // 构建查询URL
            string url = $"{_config.GetApiHost()}/status/get/prefop?id={persistentId}";

            // 发送请求
            var result = await _httpManager.CreateRequest(HttpMethod.Get, url)
                .SendAsJsonAsync(QiniuJsonSerializerContext.Default.PrefopResult);
            return result ?? new PrefopResult();
        }

        /// <summary>
        /// 根据URI的类型(网络URL或者本地文件路径)自动选择处理方法
        /// </summary>
        /// <param name="fop">文件处理命令</param>
        /// <param name="uri">资源/文件URI</param>
        /// <param name="isText">是否为文本内容</param>
        /// <returns>操作结果/返回数据</returns>
        public async Task<DfopResult> DfopAsync(string fop, string uri, bool isText = false)
        {
            if (isText)
            {
                // 如果是文本内容，则使用文本处理方法
                return await DfopTextAsync(fop, uri);
            }
            else if (Uri.TryCreate(uri, UriKind.Absolute, out Uri? uriResult) &&
                     (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps))
            {
                // 如果是网络URL，则使用URL处理方法
                return await DfopUrlAsync(fop, uri);
            }
            else
            {
                // 否则视为本地文件路径
                return await DfopFileAsync(fop, uri);
            }
        }

        /// <summary>
        /// 处理网络URL资源
        /// </summary>
        /// <param name="fop">文件处理命令</param>
        /// <param name="url">资源URL</param>
        /// <returns>处理结果</returns>
        public async Task<DfopResult> DfopUrlAsync(string fop, string url)
        {
            // 构建请求URL
            string dfopUrl = $"{_config.GetApiHost()}/dfop?fop={Uri.EscapeDataString(fop)}&url={Uri.EscapeDataString(url)}";

            // 创建认证提供者
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);

            // 发送请求
            var request = _httpManager.CreateRequest(HttpMethod.Post, dfopUrl)
                .WithAuthentication(authProvider);
            var response = await request.SendAsync();

            // 处理响应
            response.EnsureSuccessStatusCode();

            // 根据内容类型处理响应
            if (response.Content.Headers.ContentType?.MediaType?.Contains("json") == true)
            {
                try
                {
                    var result = await _httpManager.CreateRequest(HttpMethod.Post, dfopUrl)
                        .WithAuthentication(authProvider)
                        .SendAsJsonAsync(QiniuJsonSerializerContext.Default.DfopResult);
                    return result ?? new DfopResult();
                }
                catch
                {
                    // 如果JSON解析失败，则返回二进制数据
                    var result = new DfopResult
                    {
                        Data = await response.Content.ReadAsByteArrayAsync()
                    };
                    return result;
                }
            }
            else
            {
                // 非JSON响应，返回二进制数据
                var result = new DfopResult
                {
                    Data = await response.Content.ReadAsByteArrayAsync()
                };
                return result;
            }
        }

        /// <summary>
        /// 处理本地文件
        /// </summary>
        /// <param name="fop">文件处理命令</param>
        /// <param name="localFile">本地文件路径</param>
        /// <returns>处理结果</returns>
        public async Task<DfopResult> DfopFileAsync(string fop, string localFile)
        {
            // 检查文件是否存在
            if (!File.Exists(localFile))
            {
                throw new FileNotFoundException("文件不存在", localFile);
            }

            // 构建请求URL
            string dfopUrl = $"{_config.GetApiHost()}/dfop?fop={Uri.EscapeDataString(fop)}";

            // 创建认证提供者
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);

            // 准备文件内容
            using var fileStream = new FileStream(localFile, FileMode.Open, FileAccess.Read);
            var streamContent = new StreamContent(fileStream);
            streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

            // 创建多部分表单内容
            var formData = new MultipartFormDataContent
            {
                { streamContent, "data", Path.GetFileName(localFile) }
            };

            // 发送请求
            var request = _httpManager.CreateRequest(HttpMethod.Post, dfopUrl)
                .WithAuthentication(authProvider)
                .WithContent(formData);
            var response = await request.SendAsync();

            // 处理响应
            response.EnsureSuccessStatusCode();

            // 根据内容类型处理响应
            if (response.Content.Headers.ContentType?.MediaType?.Contains("json") == true)
            {
                try
                {
                    var result = await _httpManager.CreateRequest(HttpMethod.Post, dfopUrl)
                        .WithAuthentication(authProvider)
                        .SendAsJsonAsync(QiniuJsonSerializerContext.Default.DfopResult);
                    return result ?? new DfopResult();
                }
                catch
                {
                    // 如果JSON解析失败，则返回二进制数据
                    var result = new DfopResult
                    {
                        Data = await response.Content.ReadAsByteArrayAsync()
                    };
                    return result;
                }
            }
            else
            {
                // 非JSON响应，返回二进制数据
                var result = new DfopResult
                {
                    Data = await response.Content.ReadAsByteArrayAsync()
                };
                return result;
            }
        }

        /// <summary>
        /// 处理文本内容
        /// </summary>
        /// <param name="fop">文本处理命令</param>
        /// <param name="text">文本内容</param>
        /// <returns>处理结果</returns>
        public async Task<DfopResult> DfopTextAsync(string fop, string text)
        {
            // 构建请求URL
            string dfopUrl = $"{_config.GetApiHost()}/dfop?fop={Uri.EscapeDataString(fop)}";

            // 创建认证提供者
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);

            // 准备文本内容
            var stringContent = new StringContent(text, Encoding.UTF8, "text/plain");

            // 创建多部分表单内容
            var formData = new MultipartFormDataContent
            {
                { stringContent, "data", "text" }
            };

            // 发送请求
            var request = _httpManager.CreateRequest(HttpMethod.Post, dfopUrl)
                .WithAuthentication(authProvider)
                .WithContent(formData);
            var response = await request.SendAsync();

            // 处理响应
            response.EnsureSuccessStatusCode();

            // 根据内容类型处理响应
            if (response.Content.Headers.ContentType?.MediaType?.Contains("json") == true)
            {
                try
                {
                    var result = await _httpManager.CreateRequest(HttpMethod.Post, dfopUrl)
                        .WithAuthentication(authProvider)
                        .SendAsJsonAsync(QiniuJsonSerializerContext.Default.DfopResult);
                    return result ?? new DfopResult();
                }
                catch
                {
                    // 如果JSON解析失败，则返回二进制数据
                    var result = new DfopResult
                    {
                        Data = await response.Content.ReadAsByteArrayAsync()
                    };
                    return result;
                }
            }
            else
            {
                // 非JSON响应，返回二进制数据
                var result = new DfopResult
                {
                    Data = await response.Content.ReadAsByteArrayAsync()
                };
                return result;
            }
        }

        /// <summary>
        /// 处理文本文件
        /// </summary>
        /// <param name="fop">文本处理命令</param>
        /// <param name="textFile">文本文件路径</param>
        /// <returns>处理结果</returns>
        public async Task<DfopResult> DfopTextFileAsync(string fop, string textFile)
        {
            // 检查文件是否存在
            if (!File.Exists(textFile))
            {
                throw new FileNotFoundException("文件不存在", textFile);
            }

            // 读取文本文件内容
            string text = await File.ReadAllTextAsync(textFile);

            // 调用文本处理方法
            return await DfopTextAsync(fop, text);
        }
    }
}